package com.yugao.fintech.antelope.shop.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yugao.fintech.antelope.base.model.constants.CommonCons;
import com.yugao.fintech.antelope.base.model.constants.TenantCons;
import com.yugao.fintech.antelope.base.model.module.auth.AuthUserTenant;
import com.yugao.fintech.antelope.shop.assembly.StoreAssembly;
import com.yugao.fintech.antelope.shop.manager.StoreManager;
import com.yugao.fintech.antelope.shop.mapper.StoreMapper;
import com.yugao.fintech.antelope.shop.model.entity.ShopStore;
import com.yugao.fintech.antelope.shop.service.StoreService;
import com.yugao.fintech.antelope.system.SystemApi;
import com.yugao.fintech.antelope.system.model.rqrs.tenant.TenantSaveReq;
import com.yugao.fintech.antelope.system.model.rqrs.tenant.TenantUpdateReq;
import com.yugao.fintech.framework.assistant.utils.CollectionUtils;
import com.yugao.fintech.framework.assistant.utils.exception.BizException;
import com.yugao.fintech.framework.mybatisplus.utils.PageUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 门店
 *

 */
@Slf4j
@Service
public class StoreServiceImpl extends ServiceImpl<StoreMapper, ShopStore>
    implements IService<ShopStore>, StoreService {

    @Autowired
    private StoreManager storeManager;

    @Autowired
    private StoreAssembly storeAssembly;
    @Autowired
    private SystemApi systemApi;
    
    @Override
    public IPage<StoreResp> pageStore(StorePageReq req) {
        LocalDateTime beginTime = req.getBeginLocalDateTime();
        LocalDateTime endTime = req.getEndLocalDateTime();
        LambdaQueryWrapper<ShopStore> lqw = ShopStore.lqw()
            .eq(StringUtils.isNotEmpty(req.getStatus()), ShopStore::getStatus, req.getStatus())
            .ge(Objects.nonNull(beginTime), ShopStore::getCreatedAt, beginTime)
            .le(Objects.nonNull(endTime), ShopStore::getCreatedAt, endTime)
            .orderByDesc(ShopStore::getCreatedAt);
        IPage<ShopStore> pageData = this.page(PageUtil.to(req), lqw);
        return PageUtil.to(pageData, storeAssembly::toStoreResp);
    }
    
    @Override
    public List<StoreResp> listStore(StoreListReq req) {
        LambdaQueryWrapper<ShopStore> lqw = ShopStore.lqw().eq(ShopStore::getStatus, CommonCons.UseStats.NORMAL)
                .in(CollUtil.isNotEmpty(req.getTenantIds()), ShopStore::getTenantId, req.getTenantIds())
                .like(StringUtils.isNotEmpty(req.getName()), ShopStore::getName, req.getName());

        return this.list(lqw).stream()
    	        .map(storeAssembly::toStoreResp).collect(Collectors.toList());
    }

    @Override
    public StoreResp getStore(Long id) {
        ShopStore entity = this.getById(id);
    	return storeAssembly.toStoreResp(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveStore(StoreSaveReq req) {
        ShopStore entity = storeAssembly.toStore(req);

        TenantSaveReq tenantSaveReq = new TenantSaveReq();
        tenantSaveReq.setLogo(entity.getLogo()).setName(entity.getName()).setStatus(TenantCons.Status.NORMAL);
        Long tenantId = systemApi.saveTenant(tenantSaveReq);
        entity.setTenantId(tenantId);
        return this.save(entity);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStore(StoreUpdateReq req) {
        ShopStore entity = storeAssembly.toStore(req);
        ShopStore dbStore = this.getById(entity.getId());
        if (Objects.isNull(dbStore)) {
            return true;
        }
        boolean ret = this.updateById(entity);

        TenantUpdateReq updateReq = new TenantUpdateReq();
        updateReq.setId(dbStore.getTenantId()).setName(req.getName()).setLogo(req.getLogo())
                        .setStatus(req.getStatus());
        systemApi.updateTenant(updateReq);
        return ret;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteStore(Long id) {
        ShopStore shopStore = this.getById(id);
        if (Objects.isNull(shopStore)) {
            return true;
        }
        if (AuthUserTenant.mainTenant(shopStore.getMainTenantId(), shopStore.getTenantId())) {
            throw new BizException("不能操作总店");
        }
        boolean ret = this.removeById(id);
        systemApi.deleteTenant(shopStore.getTenantId());
        return ret;
    }
    
    @Override
    public boolean batchDeleteStore(List<Long> ids) {
        List<ShopStore> stores = this.listByIds(ids);
        if (CollectionUtils.isEmpty(stores)) {
            return true;
        }
        if (stores.stream().anyMatch(e -> AuthUserTenant.mainTenant(e.getMainTenantId(), e.getTenantId()))) {
            throw new BizException("不能操作总店");
        }
        boolean ret = this.removeByIds(ids);
        stores.forEach(e -> systemApi.deleteTenant(e.getTenantId()));
    	return ret;
    }

    @Override
    public ShopStore getTenantRefStore(Long tenantId) {
        return this.getOne(ShopStore.lqw().eq(ShopStore::getTenantId, tenantId));
    }
}
